Elixirで外部API呼び出しのテストをする
外部APIを呼び出すアプリケーションをテストする場合、テストのたびにリクエストを送信するのは現実的ではありませんが自作のレスポンスデータを使うと、バグをテストで発見できなくなってしまう場合があります。
できる限り本物のAPIレスポンスを使ってテストしたいです。
Elixirにはexvcrというライブラリを使うことで本物のAPIレスポンスを使ったテストが簡単に実現できます。今回はexvcrを使って外部API呼び出しのテストを書いてみます。
インストール
サンプルプロジェクトを作成し、mix.exsファイルに以下の記述を追加してインストールします。
環境構築、プロジェクトの作成方法はこのページを参照してください
MacにElixir環境を構築する
defp deps do [ {:exvcr, "~> 0.6", only: :test}, # この行を追加します ] end
以下のコマンドでインストールします
mix deps.get
テストコード
今回はGitHub APIを呼び出すアプリケーションを例にテストしてみます(テスト対象のライブラリ)。
exvcrは最初、実際にAPIをコールして返却された値をJSONに保存し、2回目以降はそのJSONの値をレスポンスとして使用します。
設定
まずtest_helper.exsファイルにJSONの保存先ディレクトリを指定します
ExUnit.start() ExVCR.Config.cassette_library_dir("test/fixture/vcr_cassettes") # この行を追加
テストコードの作成
テストコードを書きます。テスト対象はEhee.Gists
モジュールのlist
メソッドです。
defmodule Ehee.GistsTest do use ExUnit.Case, async: false use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney # この行を追加 import Ehee.Gists @credential Ehee.Credential.new(%{access_token: "yourtokencomeshere"}) setup_all do HTTPoison.start end test "list" do use_cassette "gists#list" do # テストコードをブロックで囲む all_gists = list(@credential) assert Enum.count(all_gists) > 1 end end
レスポンスデータの作成
テストを実施します。
mix test
テストを実施するとproject_root/test/fixture/vcr_cassetes
ディレクトリの下にgists#list.json
が作成されました。
次回以降のテストではこのjsonファイルの内容がレスポンスとして使用されます。
- gists#list.jsonの中身
[ { "request": { "body": "\"\"", "headers": { "Authorization": "token yourtokencomeshere" }, "method": "get", "options": [], "request_body": "", "url": "https://api.github.com/gists" }, "response": { "body": "[{\"url\":\"https://api.github.com/gists/xxxxxx\", ....}]", "headers": { "Server": "GitHub.com", "Date": "Sun, 02 Oct 2016 07:41:45 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "8413", "Status": "200 OK", ..... }, "status_code": 200, "type": "ok" } } ]
まとめ
テストコードが書きやすいのはElixirの魅力の一つですが、このライブラリを使うことでより簡単にテストをすることができます。
これ以外にもどのようなテストライブラリがあるか探ってみて、良いものがあればまた紹介します。